﻿Imports System.Drawing
Imports System.Text
Imports System.Web
Imports dooll.Config
Imports System.IO.Compression
Imports System.Net

Public Class Util
    Inherits ClsBase
    Const CryptKey As String = "CityFlyZ"

    ''' <summary>
    ''' 获得IP地址
    ''' </summary>
    ''' <returns>String 127.0.0.1</returns>
    ''' <remarks></remarks>
    Public Shared Function GetRealIP() As String
        Dim ip As String
        Try
            Dim request As HttpRequest = HttpContext.Current.Request
            If String.IsNullOrEmpty(request.ServerVariables("HTTP_VIA")) Then
                If String.IsNullOrEmpty(request.ServerVariables("HTTP_X_FORWARDED_FOR")) Then
                    ip = request.ServerVariables("HTTP_X_FORWARDED_FOR").ToString().Split(CChar(","))(0).Trim()
                Else
                    ip = "127.0.0.1"
                End If
            Else
                ip = request.UserHostAddress
            End If


            request = Nothing
        Catch ex As Exception
            ip = "127.0.0.1"
        End Try
        Return ip

    End Function


    ''' <summary>
    ''' 写日志，方便测试（看网站需求，也可以改成存入数据库）
    ''' </summary>
    ''' <param name="sPath">要写入日志的文件路径（含名称)</param>
    ''' <param name="sWord">要写入日志里的文本内容</param>
    ''' <remarks></remarks>
    Public Shared Function toLog(ByVal sPath As String, ByVal sWord As String) As Boolean
        Try
            Dim file As New IO.FileInfo(sPath)

            If Not IO.Directory.Exists(file.DirectoryName) Then
                IO.Directory.CreateDirectory(file.DirectoryName)
            End If
            IO.File.AppendAllText(sPath, String.Concat(Replace(sWord, vbCrLf, "-"), vbCrLf))
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    ''' 写入日志
    ''' </summary>
    ''' <param name="sWord"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function toLog(ByVal sWord As String) As Boolean
        Return toLog(System.Web.HttpContext.Current.Server.MapPath(String.Concat("/log/", Now.ToString("yyyyMM/dd"), ".log")), sWord)
    End Function

    ''' <summary>
    ''' 根据指定的URL获得信息
    ''' </summary>
    ''' <param name="url">url</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetHtmlFromUrl(url As String, Optional timeout As Integer = 1800) As String
        Dim strRet As String = Nothing
        If url = Nothing OrElse url.Trim().ToString() = "" Then
            Return "URL不能为空"
        End If
        Dim targeturl As String = url.Trim().ToString()
        Try
            Dim hr As HttpWebRequest = DirectCast(WebRequest.Create(targeturl), HttpWebRequest)
            hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
            hr.Method = "GET"
            hr.Timeout = timeout * 1000
            Dim hs As WebResponse = hr.GetResponse()
            Dim sr As System.IO.Stream = hs.GetResponseStream()
            Dim ser As New System.IO.StreamReader(sr, Encoding.[Default])
            strRet = ser.ReadToEnd()
        Catch ex As Exception
            strRet = ex.Message
        End Try
        Return strRet
    End Function

    ''' <summary>
    ''' 根据指定的URI获得信息
    ''' </summary>
    ''' <param name="url">url</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetHtmlFromUrl(url As System.Uri, Optional timeout As Integer = 1800) As String
        Dim strRet As String = Nothing
        If url = Nothing Then
            Return strRet
        End If
        Try
            Dim hr As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
            hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
            hr.Method = "GET"
            hr.Timeout = timeout * 1000
            Dim hs As WebResponse = hr.GetResponse()
            Dim sr As System.IO.Stream = hs.GetResponseStream()
            Dim ser As New System.IO.StreamReader(sr, Encoding.[Default])
            strRet = ser.ReadToEnd()
        Catch ex As Exception
            strRet = Nothing
        End Try
        Return strRet
    End Function

    Public Shared Function ReturnValue(ByVal Code As String, ByVal Message As String) As String
        Return String.Format("{0},{1}", Code, Message)
    End Function

    Public Shared Function ReturnValue(ByVal Code As String, ByVal Message As String, ByVal other As String) As String
        Return String.Format("{0},{1},{2}", Code, Message, other)
    End Function

    ''' <summary>
    ''' 根据文件扩展名生成随机文件名
    ''' </summary>
    ''' <param name="OriginalFileName">原文件</param>
    ''' <returns>随机文件名</returns>
    ''' <remarks></remarks>
    Public Shared Function GetRandomFileName(ByVal OriginalFileName As String) As String
        REM hhmmss随机数_原文件名
        Return String.Format("{0}{1}{2}", Now.ToString("HHmmssfff"), IO.Path.GetFileNameWithoutExtension(IO.Path.GetRandomFileName), IO.Path.GetExtension(OriginalFileName))
    End Function

    ''' <summary>
    ''' 生成日期目录
    ''' </summary>
    ''' <param name="BasePath">BasePath</param>
    ''' <returns>BasePath/yyyyMM/dd/</returns>
    ''' <remarks></remarks>
    Public Shared Function GetRandomDirectory(ByVal BasePath As String) As String
        REM 基础目录/yyyyMM/随机数/dd/
        Return String.Format("{0}/{1}/{2}/", BasePath, Now.ToString("yyyyMM"), Now.ToString("dd"))
    End Function

    ''' <summary>
    ''' 生成日期目录
    ''' </summary>
    ''' <returns>/yyyyMM/dd/</returns>
    ''' <remarks></remarks>
    Public Shared Function GetRandomDirectory() As String
        REM 基础目录/yyyyMM/随机数/dd/
        Return String.Format("/{0}/{1}/", Now.ToString("yyyyMM"), Now.ToString("dd"))
    End Function

    ''' <summary>
    ''' 生成缩略图
    ''' </summary>
    ''' <param name="originalImage">原图</param>
    ''' <param name="thumbnailPath">缩略路径</param>
    ''' <param name="width">缩略宽度</param>
    ''' <param name="height">缩略高度</param>
    ''' <param name="mode">缩略模式 101,高度自适应 102,宽度自适应 </param>
    ''' <remarks></remarks>
    Public Shared Sub MakeThumbnail(ByVal originalImage As Image, ByVal thumbnailPath As String, ByVal width As Integer, ByVal height As Integer, ByVal mode As Integer)
        If Not IO.Directory.Exists(IO.Path.GetDirectoryName(thumbnailPath)) Then
            IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(thumbnailPath))
        End If
        Dim iWidth As Integer = width
        Dim iHeight As Integer = height
        Dim X As Integer = 0
        Dim Y As Integer = 0
        Dim oW As Integer = originalImage.Width
        Dim oH As Integer = originalImage.Height

        Select Case mode
            Case 101 REM 高度自适应
                iHeight = CInt(originalImage.Height * width / originalImage.Width)
            Case 102 REM 宽度自适应
                iWidth = CInt(originalImage.Width * iHeight / originalImage.Height)
            Case 200
                If CType(originalImage.Width, Double) / CType(originalImage.Height, Double) < 1 Then
                    oH = originalImage.Height
                    oW = CInt(originalImage.Height * iWidth / iHeight)
                    Y = 0
                    X = CInt((originalImage.Width - oW) / 2)
                Else
                    oW = originalImage.Width
                    oH = CInt(originalImage.Width * height / iWidth)
                    X = 0
                    Y = CInt((originalImage.Height - oH) / 2)
                End If
            Case Else
        End Select

        Dim bmp As New System.Drawing.Bitmap(iWidth, iHeight)

        REM 设置高质量插值法
        Dim g As Graphics = System.Drawing.Graphics.FromImage(bmp)
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic

        REM 设置高质量,低速度呈现平滑程度
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality

        REM 清空画布并以白色背晾衣服色填充
        g.Clear(System.Drawing.Color.FromArgb(255, 255, 255))

        REM 在指定位置并且按指定大小绘制原图片的指定部分
        g.DrawImage(originalImage, New Rectangle(0, 0, iWidth, iHeight), New Rectangle(X, Y, oW, oH), GraphicsUnit.Pixel)

        Try
            REM 以jpg格式保存缩略图
            Dim FileInfo As New System.IO.FileInfo(thumbnailPath)
            If Not System.IO.Directory.Exists(FileInfo.DirectoryName) Then
                System.IO.Directory.CreateDirectory(FileInfo.DirectoryName)
            End If
            bmp.Save(thumbnailPath, originalImage.RawFormat)
        Catch ex As Exception
            Throw ex
        Finally
            bmp.Dispose()
            g.Dispose()
            g = Nothing
        End Try
    End Sub

#Region "加密解密区: Encrypt , Decrypt"

    REM 加密,系统密钥
    Public Shared Function Encrypt(ByVal pToEncrypt As String) As String
        Return Encrypt(pToEncrypt, CryptKey)
    End Function

    Public Shared Function Encrypt(ByVal pToEncrypt As String, ByVal sKey As String) As String
        If pToEncrypt.Length = 0 Then Return String.Empty
        If Not sKey.Length = 8 Then Return String.Empty

        Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()
        Dim ret As New StringBuilder()
        Try
            Dim inputByteArray() As Byte
            inputByteArray = Encoding.Default.GetBytes(pToEncrypt)
            '建立加密对象的密钥和偏移量
            '原文使用ASCIIEncoding.ASCII方法的GetBytes方法
            '使得输入密码必须输入英文文本
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
            '写二进制数组到加密流
            '(把内存流中的内容全部写入)
            Dim ms As New System.IO.MemoryStream()
            Dim cs As New System.Security.Cryptography.CryptoStream(ms, des.CreateEncryptor, System.Security.Cryptography.CryptoStreamMode.Write)
            '写二进制数组到加密流
            '(把内存流中的内容全部写入)
            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()

            '建立输出字符串     

            Dim b As Byte
            For Each b In ms.ToArray()
                ret.AppendFormat("{0:X2}", b)
            Next
        Catch ex As Exception

        End Try

        Return ret.ToString()
    End Function

    REM 解密
    Public Shared Function Decrypt(ByVal pToDecrypt As String) As String
        Return Decrypt(pToDecrypt, CryptKey)
    End Function

    Public Shared Function Decrypt(ByVal pToDecrypt As String, ByVal sKey As String) As String
        If pToDecrypt Is Nothing Then Return String.Empty
        If pToDecrypt.Length = 0 Then Return String.Empty
        If Not sKey.Length = 8 Then Return String.Empty
        Dim des As New System.Security.Cryptography.DESCryptoServiceProvider()

        '把字符串放入byte数组
        Try
            Dim len As Integer
            len = CInt(pToDecrypt.Length / 2 - 1)
            Dim inputByteArray(len) As Byte
            Dim x, i As Integer
            For x = 0 To len
                i = Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16)
                inputByteArray(x) = CType(i, Byte)
            Next
            '建立加密对象的密钥和偏移量，此值重要，不能修改
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
            Dim ms As New System.IO.MemoryStream()
            Dim cs As New System.Security.Cryptography.CryptoStream(ms, des.CreateDecryptor, System.Security.Cryptography.CryptoStreamMode.Write)
            cs.Write(inputByteArray, 0, inputByteArray.Length)
            cs.FlushFinalBlock()
            Return Encoding.Default.GetString(ms.ToArray)
        Catch ex As Exception
            Return String.Empty
        End Try

    End Function
#End Region

    REM 保存至缓存
    Shared Function Save2Cache(ByVal OutHtml As String, ByVal CacheFullFileName As String, ByVal CacheTime As Integer) As Boolean
        REM 缓存是否存在 ,存在则不缓存
        Return SaveString2File(OutHtml, CacheFullFileName, False)
    End Function

    REM 保存字符串至文件
    Shared Function SaveString2File(ByVal fnInputString As String, ByVal fnFilePath As String) As Boolean
        Return SaveString2File(fnInputString, fnFilePath, True)
    End Function

    Shared Function SaveString2File(ByVal fnInputString As String, ByVal fnFilePath As String, ByVal IsCrypt As Boolean) As Boolean

        REM 必要参数为空,退出返回假
        If String.IsNullOrEmpty(fnInputString) OrElse String.IsNullOrEmpty(fnFilePath) Then Return False

        Dim ReturnValue As Boolean = False

        REM 如果目录不存在,则建立
        If Not IO.Directory.Exists(IO.Path.GetDirectoryName(fnFilePath)) Then
            IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(fnFilePath))
        End If

        Dim FS As System.IO.StreamWriter
        Try
            REM 创建文件,文件不存在则创建新的
            FS = System.IO.File.CreateText(fnFilePath)

            If IsCrypt Then fnInputString = Encrypt(fnInputString)

            REM 开始写入数据
            FS.Write(fnInputString)
            FS.Close()
            FS.Dispose()
            FS = Nothing
            ReturnValue = True
        Catch ex As Exception
            ReturnValue = False
        End Try

        If Not FS Is Nothing Then
            FS.Close()
            FS.Dispose()
            FS = Nothing
        End If
        Return ReturnValue
    End Function

    ''' <summary>
    ''' 文件返回处理
    ''' </summary>
    ''' <param name="errorNumber">错误代码,0上传成功 </param>
    ''' <param name="fileUrl">url</param>
    ''' <param name="fileName">文件名</param>
    ''' <param name="customMsg">错误信息</param>
    ''' <returns>脚本字符串</returns>
    ''' <remarks></remarks>
    Public Shared Function OnUploadCompleted(ByVal errorNumber As Integer, ByVal fileUrl As String, ByVal fileName As String, ByVal customMsg As String) As String
        Return String.Format("<script>if(typeof(window.parent.OnUploadCompleted)=='function')window.parent.OnUploadCompleted({0},'{1}','{2}','{3}');</script>", errorNumber, Replace(fileUrl, "\", "/"), fileName, customMsg)
    End Function

    Public Shared Function OnUploadCompleted(ByVal str As Integer) As String
        Return String.Format("<script>if(typeof(window.parent.OnUploadCompleted)=='function')window.parent.OnUploadCompleted({0});</script>", str)
    End Function

    ''' <summary>
    ''' Zip压缩字符串
    ''' </summary>
    ''' <param name="unCompressedString"></param>
    ''' <returns>string</returns>
    ''' <remarks></remarks>
    Public Shared Function ZipString(ByVal unCompressedString As String) As String
        Dim bytData() As Byte = System.Text.Encoding.UTF8.GetBytes(unCompressedString)
        Dim ms As New IO.MemoryStream()
        Dim s As IO.Stream = New GZipStream(ms, CompressionMode.Compress)
        s.Write(bytData, 0, bytData.Length)
        s.Close()
        Dim compressedData As Byte() = ms.ToArray()
        Return System.Convert.ToBase64String(compressedData, 0, compressedData.Length)
    End Function

    ''' <summary>
    ''' Zip解缩字符串
    ''' </summary>
    ''' <param name="CompressedString"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function UnzipString(ByVal CompressedString As String) As String
        Dim unCompressedString As New System.Text.StringBuilder()
        Dim writeData(4096) As Byte
        Dim bytData As Byte() = System.Convert.FromBase64String(CompressedString)
        Dim totalLength As Integer = 0
        Dim size As Integer = 0
        Dim s As IO.Stream = New GZipStream(New IO.MemoryStream(bytData), CompressionMode.Decompress)
        While True
            size = s.Read(writeData, 0, writeData.Length)
            If size > 0 Then
                totalLength += size
                unCompressedString.Append(System.Text.Encoding.UTF8.GetString(writeData, 0, size))
            Else
                Exit While
            End If


        End While

        s.Close()
        Return unCompressedString.ToString()

    End Function


End Class
